public class ThreadTest {
    //设置结束标志位
    public static boolean isQuit=false;//首先初始值为FALSE,然后在主线程中改变
    public static void main1(String[] args) {
        //设置结束标志位在主线程在修改,结束创建的线程
        Thread thread=new Thread(()->{
            while (!isQuit){
                System.out.println("线程启动");
            }
            System.out.println("线程结束");//当isquit为TRUE时退出while循环,线程结束
        });
        thread.start();//启动线程
        try {
            Thread.sleep(1000);//休眠1秒,保证新的线程能先执行
        } catch (InterruptedException e) {//提前唤醒异常
            throw new RuntimeException(e);
        }
        isQuit=true;//改变isouit的值,使线程结束
    }

    public static void main2(String[] args) {
        //使用Thread类内置的标志符isinterrupted来设置
        Thread t=new Thread(()->{
            while (!Thread.currentThread().isInterrupted()){//获取当前线程的标志位,默认一开始为FALSE
                try {
                    System.out.println("haha");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                   e.printStackTrace();
                   break;//一定要在捕获异常后退出while循环,不然sleep会再次将标志位改为FALSE,就陷入死循环了
                }
            }
        });
        t.start();
        try {
            Thread.sleep(3000);//先让线程执行,不然看不出效果
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        t.interrupt();//设置标志位为TRUE
    }

    public volatile static int flage=0;//设置结束标志位
    public static void main3(String[] args) {
        //线程安全---->内存可见性
        Thread t1=new Thread(()->{
            while (flage==0){
                //System.out.println("没结束");
            }
            System.out.println("线程结束");
        });
        Thread t2=new Thread(()->{
            flage=1;//修改标志位的值
        });
        t1.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        t2.start();
    }

    public static void main4(String[] args) {
        //线程安全----->指令重排序
         Student[] student = new Student[1];
        Object o=new Object();
        Thread t3=new Thread(()->{
           student[0] =new Student();
        });
        Thread t4=new Thread(()->{
            if(student[0]!=null){
                student[0].add();
            }
        });
    }

    public static void main5(String[] args) {
        //wait和notify
        Object loock=new Object();//创建锁对象
        Thread t1=new Thread(()->{
            System.out.println("wait开始");
            synchronized (loock){
                try {
                    loock.wait();
                } catch (InterruptedException e) {//提前唤醒异常
                    throw new RuntimeException(e);
                }
            }
            System.out.println("wait结束");
        });
        Thread t2=new Thread(()->{
            synchronized(loock) {
                System.out.println("notify开始");
                loock.notify();//唤醒wait;
                System.out.println("notify结束");
            }
        });
        t1.start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        t2.start();
    }



    public static void main(String[] args) {
        //单例模式
        Singleton s1=Singleton.getSingleton();
        Singleton s2=Singleton.getSingleton();
        //Singleton s3=new Singleton();


    }

}
//单例类
class Singleton{
    private static Singleton singleton=new Singleton();//当前类的唯一对象(万一没有用上?
    public static Singleton getSingleton(){//只有在一种获取方法
        return singleton;
    }
    private Singleton(){}//构造方法私有化,使的在类外部不能得到当前类的对象,只有自带的

}
//单例类,使用懒汉模式
class Singleton1{
    private static Singleton1 singleton1=null;//非必要不创建
    public static Singleton1 getSingleton1(){//只有在调用方法时才创建(此时肯定需要)
        if(singleton1==null){//证明还没有实例化对象,只有第一次创建对象要加锁
            synchronized ( Singleton1.class){//对实例化的过程加锁
                if(singleton1==null){//还没创建时(
                    singleton1=new Singleton1();
                }
            }
        }
        return singleton1;
    }
    private Singleton1(){}//私有化
}
//关闭指令重排序
class Singleton2{
    volatile private static Singleton2 singleton2=null;////关闭指令重排序
    public static Singleton2 getSingleton2(){
        if(singleton2==null){
            synchronized (Singleton2.class){
                if(singleton2==null) {
                    singleton2 = new Singleton2();
                }
            }
        }
        return singleton2;
    }
}
